﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SiGeSIB.GUI.Common;
using SiGeSIB.Data.Finances;
using SiGeSIB.Services;
using System.Globalization;
using SiGeSIB.Data.Common;

namespace SiGeSIB.GUI.Finances
{
	public partial class FManageFinances : ConflictableForm, IRefreshable
	{
		#region Constructors
		public FManageFinances()
		{
			InitializeComponent();

			this.Text = "Gerenciamento de finanças";

			fManageIncomes.Type = EMovimentationType.Income;
			fManageOutcomes.Type = EMovimentationType.Outcome;
			fManageFutureReleases.Type = EMovimentationType.FutureReleases;

			fManageIncomes.StateModified += new EventHandler<EventArgs<int>>(Reload);
			fManageOutcomes.StateModified += new EventHandler<EventArgs<int>>(Reload);
			fManageFutureReleases.StateModified += new EventHandler<EventArgs<int>>(Reload);

			uFinancesDefaultToolStripIncome.GenerateReportRequested += new EventHandler(uFinancesDefaultToolStripIncome_GenerateReportRequested);
			uFinancesDefaultToolStripOutcome.GenerateReportRequested += new EventHandler(uFinancesDefaultToolStripOutcome_GenerateReportRequested);
			uFinancesToolStrip.GenerateReportRequested += new EventHandler(uFinancesToolStrip_GenerateReportRequested);

			uFinancesDefaultToolStripIncome.IntervalChanged += new EventHandler<EventArgs<SiGeSIB.Data.Common.DateTimeInterval>>(uFinancesDefaultToolStripIncome_IntervalChanged); ;
			uFinancesDefaultToolStripOutcome.IntervalChanged += new EventHandler<EventArgs<SiGeSIB.Data.Common.DateTimeInterval>>(uFinancesDefaultToolStripOutcome_IntervalChanged); ;

			fManageIncomes.RequestClose += new EventHandler<EventArgs<DialogResult>>(OnRequestClose);
			fManageOutcomes.RequestClose += new EventHandler<EventArgs<DialogResult>>(OnRequestClose);
			fManageFutureReleases.RequestClose += new EventHandler<EventArgs<DialogResult>>(OnRequestClose);

			DateTimeInterval initialInterval = new DateTimeInterval(null, DateTime.Today.Truncate());
			fManageOutcomes.SetInterval(initialInterval);
			fManageIncomes.SetInterval(initialInterval); 
			uFinancesDefaultToolStripIncome.Interval = initialInterval;
			uFinancesDefaultToolStripOutcome.Interval = initialInterval;
		}

		void uFinancesDefaultToolStripIncome_IntervalChanged(object sender, EventArgs<SiGeSIB.Data.Common.DateTimeInterval> e)
		{
			fManageIncomes.AnalysedInterval = e.Args as DateTimeInterval;
		}

		void uFinancesDefaultToolStripOutcome_IntervalChanged(object sender, EventArgs<SiGeSIB.Data.Common.DateTimeInterval> e)
		{
			fManageOutcomes.AnalysedInterval = e.Args as DateTimeInterval;
		}
		#endregion

		#region EventHandlers
		protected void OnRequestClose(object sender, EventArgs<DialogResult> e)
		{
			if (RequestClose != null)
				RequestClose(sender, new EventArgs<DialogResult>(e.Args));
		}

		void uFinancesDefaultToolStripIncome_GenerateReportRequested(object sender, EventArgs e)
		{
			if (saveFileDialog1.ShowDialog() == DialogResult.OK)
			{
				fManageIncomes.ExportMovimentations(saveFileDialog1.FileName);
			}
		}

		void uFinancesDefaultToolStripOutcome_GenerateReportRequested(object sender, EventArgs e)
		{
			if (saveFileDialog1.ShowDialog() == DialogResult.OK)
			{
				fManageOutcomes.ExportMovimentations(saveFileDialog1.FileName);
			}
		}

		void uFinancesToolStrip_GenerateReportRequested(object sender, EventArgs e)
		{
			if (saveFileDialog1.ShowDialog() == DialogResult.OK)
			{
				fManageFutureReleases.ExportMovimentations(saveFileDialog1.FileName);
			}
		}

		private void _FillValues(decimal incomeRecent, decimal outcomeRecent, decimal incomeFuture, decimal outcomeFuture)
		{
			txtRecentIncome.Text = incomeRecent.ToString(CultureInfo.InvariantCulture);
			txtRecentOutcome.Text = outcomeRecent.ToString(CultureInfo.InvariantCulture);
			txtFutureIncome.Text = incomeFuture.ToString(CultureInfo.InvariantCulture);
			txtFutureOutcome.Text = outcomeFuture.ToString(CultureInfo.InvariantCulture);

			decimal totalRecent = incomeRecent - outcomeRecent;
			txtRecentBalance.Text = totalRecent.ToString(CultureInfo.InvariantCulture);
			if (totalRecent < 0)
				lblBalance.ForeColor = txtRecentBalance.ForeColor = Color.Red;
			else
				lblBalance.ForeColor = txtRecentBalance.ForeColor = Color.Green;

			decimal totalFuture = incomeFuture - outcomeFuture;
			txtFutureBalance.Text = totalFuture.ToString(CultureInfo.InvariantCulture);
			if (totalFuture < 0)
				lblFutureBalance.ForeColor = txtFutureBalance.ForeColor = Color.Red;
			else
				lblFutureBalance.ForeColor = txtFutureBalance.ForeColor = Color.Green;
		}

		private void bwBalance_DoWork(object sender, DoWorkEventArgs e)
		{
			IFinancesServicesProvider finProv = Manager.Instance.ServicesProvider.CreateFinancesServicesProvider();
			MovimentationFilter filter = new MovimentationFilter() { DesiredInterval = new DateTimeInterval(null, DateTime.Today.AddMonths(1).Truncate()) };
			List<Movimentation> movimentations = finProv.GetMovimentations(filter, MovimentationInfo.GeneralData);

			decimal totalRecentIncome = 0M;
			decimal totalRecentOutcome = 0M;
			decimal totalFutureIncome = 0M;
			decimal totalFutureOutcome = 0M;

			if(!movimentations.IsNullOrEmpty())
				foreach (Movimentation m in movimentations)
				{
					if (!m.IsFutureMovimentation)
					{
						switch (m.Type)
						{
							case EMovimentationType.Income:
								totalRecentIncome += m.Amount;
								break;
							case EMovimentationType.Outcome:
								totalRecentOutcome += m.Amount;
								break;
						}
					}
					else
					{
						switch (m.Type)
						{
							case EMovimentationType.Income:
								totalFutureIncome += m.Amount;
								break;
							case EMovimentationType.Outcome:
								totalFutureOutcome += m.Amount;
								break;
						}
					}
				}

			e.Result = new decimal[] { totalRecentIncome, totalRecentOutcome, totalFutureIncome, totalFutureOutcome };
		}

		private void bwBalance_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			if (!IsDisposed)
			{
				if (e.Error == null)
				{
					decimal[] values = e.Result as decimal[];
					if (values.Length == 4)
						_FillValues(values[0], values[1], values[2], values[3]);
				}
			}
		}
		#endregion

		#region Methods
		#region Loading
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            _LoadData();
        }

        private void _LoadData()
        {
            if (!bwBalance.IsBusy)
                bwBalance.RunWorkerAsync();
        }
        #endregion
		#endregion

		#region IRefreshable Members

		public void Reload(object sender, EventArgs<int> args)
		{
			fManageIncomes.Reload(this, new EventArgs<int>(-1));
			fManageOutcomes.Reload(this, new EventArgs<int>(-1));
			fManageFutureReleases.Reload(this, new EventArgs<int>(-1));
			_LoadData();
		}

		#endregion
	}
}
